﻿using System;
using System.Linq;
using System.Threading.Tasks;
using System.Transactions;
using Elsa.Services.Models;
using HengTong.Model;
using HengTong.Model._Admin;
using HengTong.Model.Db.Hr;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TiaoTaoHelper.Wtm.Interfaces;
using TiaoTaoHelper.Wtm.Models;
using TiaoTaoHelper.Wtm.Workflow;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.WorkFlow;

namespace HengTong.ViewModel.Hr.SysHrOnboardingRequestBillVms;

public partial class SysHrOnboardingRequestBillVm
{
    [WorkflowOperation("驳回", "将单据状态设置为草稿", "入职申请")]
    public async Task Reject(ActivityExecutionContext context)
    {
        Entity.BillStatus = BillStatus.草稿;
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        DC.UpdateProperty(Entity, x => x.BillStatus);
        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("取消", "将流程状态设置为取消", "入职申请")]
    public async Task Cancel(ActivityExecutionContext context)
    {
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        if (Entity is IBill bill)
        {
            bill.WorkflowStatus = WorkflowStatus.已取消;
            DC.UpdateProperty(Entity, x => x.WorkflowStatus);
        }

        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("完成", "将流程状态设置为已完成", "入职申请")]
    public async Task Complete(ActivityExecutionContext context)
    {
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        if (Entity is IBill bill)
        {
            bill.WorkflowStatus = WorkflowStatus.已完成;
            DC.UpdateProperty(Entity, x => x.WorkflowStatus);
        }

        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("更新档案", "将入职单据数据更新到人员档案", "入职申请")]
    public async Task UpdatePersonArchive(ActivityExecutionContext context)
    {
        // 获取日志记录器
        using var scope = Wtm.ServiceProvider.CreateScope();
        var logger = scope.ServiceProvider.GetRequiredService<ILogger<SysHrOnboardingRequestBillVm>>();

        // 获取当前操作用户
        string currentUser = "workflow";
        if (context.Input is WtmApproveInput input)
        {
            currentUser = input.CurrentUser?.ITCode ?? "workflow";
        }

        logger.LogInformation("开始更新人员档案，单据ID：{EntityId}，工号：{StaffNo}，操作用户：{User}",
            Entity?.ID, Entity?.StaffNo, currentUser);

        // 验证入职单据
        if (Entity == null || Entity.ID == Guid.Empty)
        {
            logger.LogError("入职单据不存在");
            MSD.AddModelError(" ", "入职单据不存在");
            return;
        }

        // 事务处理
        using var transactionScope = new TransactionScope(
            TransactionScopeOption.Required,
            new TransactionOptions
            {
                IsolationLevel = IsolationLevel.ReadCommitted,
                Timeout = TimeSpan.FromMinutes(10)
            },
            TransactionScopeAsyncFlowOption.Enabled);

        try
        {
            // 直接使用 ExecuteUpdateAsync 更新指定字段，避免实体跟踪和主键冲突
            var currentTime = DateTime.Now;
            var updatedRows = await DC.Set<SysPerson>()
                .Where(x => x.GetType() == typeof(SysPerson))
                .Where(p => p.StaffNo == Entity.StaffNo)
                .ExecuteUpdateAsync(p => p
                    // 工作信息
                    .SetProperty(x => x.OrgId, Entity.OrgId)
                    .SetProperty(x => x.GroupId, Entity.GroupId)
                    .SetProperty(x => x.JobPositionId, Entity.JobPositionId)
                    .SetProperty(x => x.ResumeId, Entity.ResumeId)
                    .SetProperty(x => x.JoinWorkDate, Entity.JoinWorkDate)
                    .SetProperty(x => x.HireDate, Entity.HireDate)
                    .SetProperty(x => x.EmploymentType, Entity.EmploymentType)
                    .SetProperty(x => x.ContractType, Entity.ContractType)
                    .SetProperty(x => x.ContractNo, Entity.ContractNo)
                    .SetProperty(x => x.ContractStartDate, Entity.ContractStartDate)
                    .SetProperty(x => x.ContractEndDate, Entity.ContractEndDate)
                    .SetProperty(x => x.State, PersonState.试用期)
                    // 更新时间和人员
                    .SetProperty(x => x.UpdateTime, currentTime)
                    .SetProperty(x => x.UpdateBy, currentUser)
                );

            if (updatedRows == 0)
            {
                var error = $"未找到工号为 {Entity.StaffNo} 的人员档案";
                logger.LogError(error);
                throw new Exception(error);
            }

            logger.LogInformation("成功更新人员档案，影响 {Count} 行", updatedRows);

            // 更新入职单据状态
            Entity.WorkflowStatus = WorkflowStatus.已完成;
            DC.UpdateProperty(Entity, x => x.WorkflowStatus);

            // 更新用户信息
            if (Entity.PhotoId != null || Entity.Phone != null || Entity.Name != null)
            {
                var userUpdatedRows = await DC.Set<FrameworkUser>().Where(u => u.ITCode == Entity.StaffNo)
                    .ExecuteUpdateAsync(u => u
                        .SetProperty(x => x.PhotoId, Entity.PhotoId)
                        .SetProperty(x => x.CellPhone, Entity.Phone)
                        .SetProperty(x => x.Name, Entity.Name));

                logger.LogInformation("更新用户信息完成，影响{Count}行", userUpdatedRows);
            }

            await DC.SaveChangesAsync();
            transactionScope.Complete();

            logger.LogInformation("人员档案更新成功");

            // 事务提交后清理用户缓存
            if (Entity.PhotoId != null || Entity.Phone != null || Entity.Name != null)
            {
                await Wtm.RemoveUserCache(Entity.StaffNo);
                logger.LogWarning("用户缓存清理完成");
            }
        }
        catch (Exception e)
        {
            logger.LogError(e, "更新人员档案失败：{Message}", e.Message);
            MSD.AddModelError(" ", $"更新人员档案失败: {e.Message}");
        }
    }
}